package org.jay.angla.activity;

import java.util.List;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.ViewById;
import org.jay.angla.device.OnlabUVDevice;
import org.jay.angla.dialog.BleSelectDialog;
import org.jay.angla.dialog.HistoryExperimentDialog;
import org.jay.angla.dialog.SystemSettingDialog;
import org.jay.angla.dialog.WavelengthDialog;
import org.jay.angla.fragment.FragmentCallbackListener;
import org.jay.angla.fragment.FragmentMain;
import org.jay.angla.fragment.FragmentPhotometryMeasurement;
import org.jay.angla.fragment.FragmentQuantitativeAnalysis;
import org.jay.angla.fragment.FragmentTimeScanning;
import org.jay.angla.fragment.FragmentWavelengthScanning;
import org.jay.angla.onlab.OnlabApplication;
import org.jay.angla.onlab.R;
import org.jay.angla.popwindow.PopWinTool;
import org.jay.angla.utils.Contants;
import org.jay.angla.utils.ToastShow;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.TextView;

@SuppressLint({ "NewApi", "HandlerLeak" })
@EActivity(R.layout.activity_main)
public class MainActivity extends Activity implements FragmentCallbackListener,
		OnClickListener {

	@SystemService
	WindowManager windowManager;
	@ViewById(R.id.mTitleTextView)
	TextView mTitleTextView;
	@ViewById(R.id.title_tool)
	ImageView mTitleToolImageView;
	@ViewById
	TextView mWavelengthTextView;
	@ViewById
	TextView mAbsTextView;
	@ViewById
	TextView mTransTextView;
	@ViewById
	ImageView mBTImageView;
	@ViewById
	TextView mBTTextView;

	private FragmentMain mMain;
	private FragmentPhotometryMeasurement mPhotometryMeasurement;
	private FragmentQuantitativeAnalysis mQuantitativeAnalysis;
	private FragmentTimeScanning mTimeScanning;
	private FragmentWavelengthScanning mWavelengthScanning;
	private static boolean isExit = false;
	private ToastShow mToast;

	private PopWinTool mPopWinTool;

	private boolean isRunning = false;
	private int[] darkCurrent;
	private int I0 = 20000;
	private int ga = -1;
	private float mWavelength;
	private float mAbs;
	private float mTrans;
	private int mEnergy;
	private DeviceCmdHandler mCmdHandler;
	private WavelengthDialog mWavelengthDialog;

	private boolean pause = false;
	private boolean pause2 = false;
	private boolean isRezeroing = false;
	private int mFreq = 2000;
	private HistoryExperimentDialog mHistoryExperimentDialog;

	// ////////////////////CODE FOR WAVELENGTH SCANNING///////////////////////
	private int currA = 8;
	private float currWl = 1100.0f;
	private float startWl;
	private float endWl;
	private float intervalWl;
	private boolean lastIsIncrease = false;
	private int[] baseline;
	private int[] I00;
	private int gaa[];
	private boolean baselineRunning = false;

	// ////////////////////CODE FOR WAVELENGTH SCANNING///////////////////////
	private float startTestWl;
	private float endTestWl;
	private float intervaTestlWl;
	private float currTestWl;
	private boolean wsTestRunning = false;
	private ProgressDialog mWavelengthResetDialog;

	private BleSelectDialog mBleSelectDialog;

	private SystemSettingDialog mSystemSettingDialog;

	private boolean isDeviceConnected = false;

	public void setFreq(int freq) {
		mFreq = freq;
	}

	@AfterViews
	void init_ui() {
		mTitleTextView.setText(getString(R.string.main_ui_string));
		mTitleToolImageView.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				showPopWindow(v);
			}
		});
		mBTImageView.setOnClickListener(this);
		darkCurrent = new int[8];
		HandlerThread handlerThread = new HandlerThread("handler_thread");
		handlerThread.start();
		mCmdHandler = new DeviceCmdHandler(handlerThread.getLooper());
		baseline = new int[911];
		I00 = new int[911];
		gaa = new int[911];
		// connect ble auto
		// new Thread(new Runnable() {
		//
		// @Override
		// public void run() {
		// // TODO Auto-generated method stub
		// try {
		// Thread.sleep(1000);
		// Log.d(Contants.TAG, "address = "
		// + OnlabApplication.getInstance().getSpUtil()
		// .getBtAddress());
		// if (!OnlabApplication.getInstance().getSpUtil()
		// .getBtAddress().startsWith("null")) {
		// OnlabUVDevice.getInstance().connect(
		// OnlabApplication.getInstance().getSpUtil()
		// .getBtAddress());
		// }
		// } catch (InterruptedException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		//
		// }
		// }).start();

	}

	private void showPopWindow(View view) {
		if (mPopWinTool == null) {
			View.OnClickListener popListener = new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					switch (v.getId()) {
					case R.id.layout_dark_current:
						mCmdHandler
								.sendEmptyMessage(OnlabUVDevice.CMD_GET_DARK_CURRENT);
						break;
					case R.id.layout_rezero:
						rezero();
						break;

					case R.id.layout_set_wavelength:
						showWavelengthReset();
						showSetWavelengthDialog();
						break;

					case R.id.layout_save:
						save();
						break;

					case R.id.layout_open:
						open();
						break;

					case R.id.layout_param_setting:
						param_setting();
						break;
					case R.id.layout_system_baseline:
						if (mWavelengthScanning.isAdded()) {
							mWavelengthScanning.systemBaseline();
						}
						break;
					case R.id.layout_system_setting:
						mSystemSettingDialog.show();
						break;

					default:
						break;
					}
					mPopWinTool.dismiss();
				}
			};
			mPopWinTool = new PopWinTool(this, popListener,
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

		}
		mPopWinTool.setFocusable(true);
		mPopWinTool.showAsDropDown(view, 0 - 130, 0);
		mPopWinTool.update();
	}

	class DeviceCmdHandler extends Handler {

		public DeviceCmdHandler() {
		}

		public DeviceCmdHandler(Looper looper) {
			super(looper);
		}

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			// super.handleMessage(msg);
			Bundle bundle = msg.getData();
			switch (msg.what) {
			case OnlabUVDevice.CMD_GET_A:
				OnlabUVDevice.getInstance().getA();
				break;
			case OnlabUVDevice.CMD_GET_DARK_CURRENT:
				OnlabUVDevice.getInstance().getDark();
				break;
			case OnlabUVDevice.CMD_GET_ENERGY:
				OnlabUVDevice.getInstance().getEnergy();
				break;
			case OnlabUVDevice.CMD_GET_WAVELENGTH:
				OnlabUVDevice.getInstance().getWaveLength();
				break;
			case OnlabUVDevice.CMD_RESET_DARK:
				OnlabUVDevice.getInstance().reSetDark();
				break;
			case OnlabUVDevice.CMD_REZERO:
				OnlabUVDevice.getInstance().reZero();
				break;
			case OnlabUVDevice.CMD_SET_WAVELENGTH:
				float wl = bundle.getFloat("WL");
				OnlabUVDevice.getInstance().setWavelength(wl);
				// mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_WAVELENGTH);
				break;
			case OnlabUVDevice.CMD_SET_A:
				int sa = bundle.getInt("SA");
				OnlabUVDevice.getInstance().setA(sa);
				break;

			default:
				break;
			}
		}
	}

	private Handler mOnlabHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case OnlabUVDevice.DEVICE_SCANNING:
				Bundle b = msg.getData();
				String name = b.getString("DEVICE_NAME");
				String address = b.getString("DEVICE_ADDRESS");
				Log.d(Contants.TAG, "name: " + name + ", address: " + address);
				mBleSelectDialog.addOneDevice(name, address, false);

				break;
			case OnlabUVDevice.DEVICE_CONNECT_STATE:
				int state = msg.arg1;
				if (state == OnlabUVDevice.DEVICE_CONNECT_STATE_CONNECTED) {
					mToast.toastShow(getString(R.string.BT_CONNECTED_SUCCESS));
					setBleConnected();
				} else if (state == OnlabUVDevice.DEVICE_CONNECT_STATE_CONNECTING) {
					mToast.toastShow(getString(R.string.BT_CONNECTING));
				} else if (state == OnlabUVDevice.DEVICE_CONNECT_STATE_DISCONNECTED) {
					mToast.toastShow(getString(R.string.BT_DISCONNECTED_SUCCESS));
					setBleDisconnected();
				} else if (state == OnlabUVDevice.DEVICE_CONNECT_STATE_TIMEOUT) {
					mToast.toastShow(getString(R.string.BT_CONNECTED_TIMEOUT));
				}
				break;

			case OnlabUVDevice.DEVICE_MESSAGE_COMMING:
				int cmd = msg.arg1;
				if (cmd == OnlabUVDevice.DEVICE_MESSAGE_DATA) {
					Bundle bundle = msg.getData();
					byte[] data = bundle.getByteArray("RECV_DATA");
					// Log.d(Contants.TAG, "length = " + data.length);
					String message = new String(data);
					// Log.d(Contants.TAG, String.format("[%s]", message));

					String[] msgs = message.split("\r\n");
					if (msgs.length >= 2) {
						if (msgs[1].startsWith("Invalid")) {
							mToast.toastShow("Invalid Command!");
							return;
						}
					}
					if (msgs[0].startsWith("connect")
							&& msgs[1].startsWith("ok.")) {
						isDeviceConnected = true;
						mToast.toastShow(getString(R.string.CONNECT_TO_ANGLA_DEVICE));
						if (!isRunning) {
							isRunning = true;
							new Thread() {
								public void run() {
									// OnlabUVDevice.getInstance().getDark();
									mCmdHandler
											.sendEmptyMessage(OnlabUVDevice.CMD_GET_DARK_CURRENT);
									// OnlabUVDevice.getInstance().getWaveLength();
									mCmdHandler
											.sendEmptyMessage(OnlabUVDevice.CMD_GET_WAVELENGTH);
									// OnlabUVDevice.getInstance().getA();
									mCmdHandler
											.sendEmptyMessage(OnlabUVDevice.CMD_GET_A);

									while (isRunning) {
										try {
											// OnlabUVDevice.getInstance()
											// .getEnergy();
											if (!OnlabUVDevice.getInstance()
													.isBusy()
													&& !pause
													&& !pause2 && !isRezeroing) {
												// Log.d(Contants.TAG,
												// "running...");
												mCmdHandler
														.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
											}
											Thread.sleep(mFreq);
										} catch (InterruptedException e) {
											// TODO Auto-generated catch block
											e.printStackTrace();
										}
									}
									// Log.d(Contants.TAG, "end...");

								};
							}.start();
						}
					} else if (msgs[0].startsWith("ge 10")) {
						int[] energies = new int[10];
						int I1 = 0;
						float trans = 0;
						float abs = 0;
						for (int i = 0; i < 10; i++) {
							energies[i] = Integer.parseInt(msgs[1 + i]);
							I1 += energies[i];
						}

						I1 = I1 / 10;
						// set energy
						// Log.d(Contants.TAG, "get energy = " + I1);
						// debug code by Jay
						if (pause) {
							// Log.d(Contants.TAG, "do baseline");
							doBaseline(I1);
						} else {
							// Log.d(Contants.TAG, "do not baseline");
						}

						setEnergy(I1);
						// Log.d(Contants.TAG, "ga = " + ga);
						if (ga > 0) {
							if (!pause2) {
								trans = (float) (I1 - darkCurrent[ga - 1])
										/ (float) (I0 - darkCurrent[ga - 1]);
								setTrans(trans);
								if (trans < 0.01f) {
									abs = 4.0f;
								} else {
									abs = (float) -Math.log10(trans);
									if (abs < -4.0f) {
										abs = -4.0f;
									}
								}

							} else {
								// Log.d(Contants.TAG,
								// "##########WL = "
								// + (currTestWl + intervaTestlWl)
								// + ", GA = "
								// + gaa[(int) (currTestWl + intervaTestlWl) -
								// 190]
								// + ", id = "
								// + ((int) (currTestWl + intervaTestlWl) -
								// 190));

								if (gaa[(int) (currTestWl + intervaTestlWl) - 190] <= 0) {
									doRezero(endTestWl, -1, -1, -1);
									return;
								}
								trans = (float) (I1 - darkCurrent[gaa[(int) (currTestWl + intervaTestlWl) - 190] - 1])
										/ (float) (I00[(int) (currTestWl + intervaTestlWl) - 190] - darkCurrent[gaa[(int) (currTestWl + intervaTestlWl) - 190] - 1]);

								setTrans(trans);
								if (trans < 0.01f) {
									abs = 4.0f;
								} else {
									abs = (float) -Math.log10(trans);
									if (abs < -4.0f) {
										abs = -4.0f;
									}
								}
							}
							setAbs(abs);
							// Log.d(Contants.TAG, "abs = " + abs);
						}
						if (pause2) {
							doTest(currTestWl, abs, trans, I1);
						}

						if (isRezeroing) {
							doRezero(currTestWl, abs, trans, I1);
						}

					} else if (msgs[0].startsWith("getwl")) {
						float waveLength = Float.parseFloat(msgs[1]);
						setWavelength(waveLength);
					} else if (msgs[0].startsWith("getdark")) {
						for (int i = 0; i < 8; i++) {
							darkCurrent[i] = Integer.parseInt(msgs[1 + i]);
						}
					} else if (msgs[0].startsWith("ga")) {
						ga = Integer.parseInt(msgs[1]);
					} else if (msgs[0].startsWith("rezero")) {
						ga = Integer.parseInt(msgs[2]);
						I0 = Integer.parseInt(msgs[1]);
						if (isRezeroing) {
							gaa[(int) (currTestWl + intervaTestlWl) - 190] = ga;
							I00[(int) (currTestWl + intervaTestlWl) - 190] = I0;
							Log.d(Contants.TAG,
									"########ga = "
											+ ga
											+ ", id = "
											+ ((int) (currTestWl + intervaTestlWl) - 190));
						}

					} else if (msgs[0].startsWith("resetdark")) {
						for (int i = 0; i < 8; i++) {
							darkCurrent[i] = Integer.parseInt(msgs[1 + i]);
							// Log.d(Contants.TAG, "" + i + " => " + msgs[1 +
							// i]);
						}
					} else if (msgs[0].startsWith("swl")) {
						dismissWavelengthReset();
					}
				}
				break;

			default:
				break;
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		mMain = new FragmentMain();
		mPhotometryMeasurement = new FragmentPhotometryMeasurement();
		mQuantitativeAnalysis = new FragmentQuantitativeAnalysis();
		mTimeScanning = new FragmentTimeScanning();
		mWavelengthScanning = new FragmentWavelengthScanning();

		mWavelengthDialog = new WavelengthDialog(this);
		mWavelengthDialog.setOnClickListener(this);

		mHistoryExperimentDialog = new HistoryExperimentDialog(this);
		mHistoryExperimentDialog
				.setOnHistoryListener(new OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> parent, View view,
							int pos, long id) {
						// TODO Auto-generated method stub
						mHistoryExperimentDialog.dismiss();

						switch (mHistoryExperimentDialog.getId()) {
						case 0:
							mPhotometryMeasurement.loadHistoryById(pos);
							if (!mPhotometryMeasurement.isAdded()) {
								onMainClick(mMain
										.getViewById(mHistoryExperimentDialog
												.getId()));
							}
							break;
						case 1:
							mQuantitativeAnalysis.loadHistoryById(pos);
							if (!mQuantitativeAnalysis.isAdded()) {
								onMainClick(mMain
										.getViewById(mHistoryExperimentDialog
												.getId()));
							}
							break;
						case 2:
							mWavelengthScanning.loadHistoryById(pos);
							if (!mWavelengthScanning.isAdded()) {
								onMainClick(mMain
										.getViewById(mHistoryExperimentDialog
												.getId()));
							}
							break;
						case 3:
							mTimeScanning.loadHistoryById(pos);
							if (!mTimeScanning.isAdded()) {
								onMainClick(mMain
										.getViewById(mHistoryExperimentDialog
												.getId()));
							}
							break;
						default:
							break;
						}
					}

				});

		addContentFragment(mMain);
		mToast = new ToastShow(this);
		OnlabUVDevice.getInstance().init(this);
		OnlabUVDevice.getInstance().register(mOnlabHandler);
		mBleSelectDialog = new BleSelectDialog(this);
		mSystemSettingDialog = new SystemSettingDialog(this);
		// check bt is enable
		final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
		BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
		if (mBluetoothAdapter == null) {
			mToast.toastShow(getString(R.string.bt_not_supported));
			finish();
		}
		if (!mBluetoothAdapter.isEnabled()) {
			Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(intent, 1);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == 1) {
			if (resultCode == RESULT_OK) {
				mToast.toastShow(getString(R.string.bt_already_open));
			} else if (resultCode == RESULT_CANCELED) {
				mToast.toastShow(getString(R.string.bt_not_allow));
				finish();
			}
		}
	}

	protected void disconnectBle() {
		AlertDialog.Builder builder = new Builder(this);
		builder.setMessage(getString(R.string.sure_to_disconnect_ble));
		builder.setTitle(getString(R.string.notice_string));
		builder.setPositiveButton(getString(R.string.sure),
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						OnlabUVDevice.getInstance().disconnect();
						isRunning = false;
						dialog.dismiss();
					}
				});
		builder.setNegativeButton(getString(R.string.cancel),
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int arg1) {
						// TODO Auto-generated method stub
						dialog.dismiss();
					}
				});
		builder.create().show();
	}

	private Handler mTimeoutHandler = new Handler() {
		public void handleMessage(Message msg) {
			dismissWavelengthReset();
			mToast.toastShow(getString(R.string.wait_timeout));
		};
	};

	private Runnable mCallback = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (mWavelengthResetDialog.isShowing()) {
				mTimeoutHandler.sendEmptyMessage(-1);
			}
		}
	};

	public void showWavelengthReset() {
		mWavelengthResetDialog = ProgressDialog.show(this,
				getString(R.string.loading),
				getString(R.string.loading_waiting), true, false);
		mTimeoutHandler.postDelayed(mCallback, 30000);
	}

	public void dismissWavelengthReset() {
		if (mWavelengthResetDialog == null)
			return;
		if (mWavelengthResetDialog.isShowing()) {
			mTimeoutHandler.removeCallbacks(mCallback);
			mWavelengthResetDialog.dismiss();
		}
	}

	public void showSetWavelengthDialog() {
		mWavelengthDialog.show();
	}

	public void dismissSetWavelengthDialog() {
		mWavelengthDialog.dismiss();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		OnlabUVDevice.getInstance().unregister();
		OnlabUVDevice.getInstance().release();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		setMainButtonsEnable();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub

		if (mPhotometryMeasurement.isSelectMode()) {
			mPhotometryMeasurement.onBack();
			return;
		} else if (mQuantitativeAnalysis.isSelectMode()) {
			mQuantitativeAnalysis.onBack();
			return;
		}

		if (!mPhotometryMeasurement.isSaved()) {
			save();
			return;
		}

		if (mPhotometryMeasurement.isAdded() || mQuantitativeAnalysis.isAdded()
				|| mTimeScanning.isAdded() || mWavelengthScanning.isAdded()) {
			mTitleTextView.setText(getString(R.string.main_ui_string));
			super.onBackPressed();
			return;
		}

		if (!isExit) {
			isExit = true;
			mToast.toastShow(getString(R.string.retry_to_exit));
			new Handler() {

				@Override
				public void handleMessage(Message msg) {
					super.handleMessage(msg);
					isExit = false;
				}
			}.sendEmptyMessageDelayed(0, 2000);
		} else {
			OnlabUVDevice.getInstance().quit();
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			finish();
			System.exit(0);
		}
	}

	public void goHome(Fragment fragment) {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction transaction = fm.beginTransaction();
		transaction.remove(fragment);
		transaction.commit();
	}

	private void addContentFragment(Fragment fragment) {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction transaction = fm.beginTransaction();

		if (fragment != mMain) {
			transaction.setCustomAnimations(
					R.animator.fragment_slide_left_enter,
					R.animator.fragment_slide_right_exit);
		}

		transaction.add(R.id.layout_content, fragment);
		transaction.addToBackStack(null);
		transaction.commit();
	}

	@Override
	public void onMainClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_guangduceliang:
			addContentFragment(mPhotometryMeasurement);
			mTitleTextView
					.setText(getString(R.string.photo_measurement_string));
			break;
		case R.id.btn_dingliangfenxi:
			addContentFragment(mQuantitativeAnalysis);
			mTitleTextView
					.setText(getString(R.string.quantitation_analysis_string));
			break;
		case R.id.btn_shijiansaomiao:
			addContentFragment(mTimeScanning);
			mTitleTextView.setText(getString(R.string.time_scanning_string));
			break;
		case R.id.btn_bochangsaomiao:
			addContentFragment(mWavelengthScanning);
			mTitleTextView
					.setText(getString(R.string.wavelength_scanning_string));
			break;
		case R.id.btn_about:
			Intent intent = new Intent(this, AboutActivity_.class);
			startActivity(intent);
			break;
		default:
			break;
		}
	}

	private void setWavelength(float wl) {
		mWavelength = wl;
		mWavelengthTextView.setText(getString(R.string.bottom_bar_wavelength)
				+ String.format("%.02f", wl) + " nm");
	}

	private void setAbs(float abs) {
		mAbs = abs;
		mAbsTextView.setText(getString(R.string.bottom_bar_abs)
				+ String.format("%.04f", abs));
	}

	private void setTrans(float trans) {
		mTrans = trans;
		mTransTextView.setText(getString(R.string.bottom_bar_trans)
				+ String.format("%.02f", trans * 100) + "%");
	}

	private void setEnergy(int energy) {
		mEnergy = energy;
	}

	private void setBleConnected() {
		mBTTextView.setText(getString(R.string.connected));
		mBTImageView.setImageResource(R.drawable.bluetooth_enable);
		String address = OnlabUVDevice.getInstance().getAddress();
		Log.d(Contants.TAG, "save address = " + address);
		OnlabApplication.getInstance().getSpUtil().saveBtAddress(address);
	}

	private void setBleDisconnected() {
		mBTTextView.setText(getString(R.string.disconnect));
		mBTImageView.setImageResource(R.drawable.bluetooth_disable);
	}

	public float getWavelength() {
		return mWavelength;
	}

	public float getAbs() {
		return mAbs;
	}

	public float getTrans() {
		return mTrans;
	}

	public int getEnergy() {
		return mEnergy;
	}

	public void setWL(float wl) {
		Message msg = mCmdHandler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putFloat("WL", wl);
		msg.setData(bundle);
		msg.what = OnlabUVDevice.CMD_SET_WAVELENGTH;
		msg.sendToTarget();
	}

	public void setA(int sa) {
		Message msg = mCmdHandler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putInt("SA", sa);
		msg.setData(bundle);
		msg.what = OnlabUVDevice.CMD_SET_A;
		msg.sendToTarget();
		ga = sa;
	}

	public void rezero() {
		mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_REZERO);
	}

	public void prepareBaseline(float start, float end, float interval) {
		startWl = start;
		currWl = end;
		endWl = end;
		intervalWl = interval;
		currA = 8;
		lastIsIncrease = false;
		baselineRunning = true;
	}

	public void stopBaseline() {
		baselineRunning = false;
	}

	public void doBaseline(int energy) {
		int index = 0;
		pause = true;

		if (!baselineRunning)
			return;

		if (energy == -1) {
			setWL(endWl);
			setA(currA);
			mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
		} else {
			if (energy >= 40000) {
				lastIsIncrease = true;
				currA = currA - 1;
				if (currA <= 0) {
					// Log.e(Contants.TAG, "currA = " + currA);
					// maybe this is workarround
					currA = 1;
					mWavelengthScanning.updateBaseline(currWl, currA, energy);
					// Log.d(Contants.TAG, "wl = " + currWl + ", a = " + currA
					// + ", energy = " + energy);
					// save baseline
					index = (int) currWl - 190;
					baseline[index] = currA;
					// Log.d(Contants.TAG, "save " + index + " = " + currA);
					if (currWl != startWl) {
						currWl = currWl - intervalWl;
						setWL(currWl);
						setA(currA);
						mCmdHandler
								.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
					} else {
						// Log.d(Contants.TAG, "wl = done2!!!!");
						baseline_finish();
					}
					// return;
				}
				setA(currA);
				mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
			} else if (energy <= 20000) {
				if (lastIsIncrease) {
					lastIsIncrease = false;
					mWavelengthScanning.updateBaseline(currWl, currA, energy);
					// Log.d(Contants.TAG, "wl = " + currWl + ", a = " + currA
					// + ", energy = " + energy);
					// save baseline
					index = (int) currWl - 190;
					baseline[index] = currA;
					// Log.d(Contants.TAG, "save " + index + " = " + currA);
					if (currWl != startWl) {
						currWl = currWl - intervalWl;
						setWL(currWl);
						setA(currA);
						mCmdHandler
								.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
					} else {
						// Log.d(Contants.TAG, "wl = done1!!!!");
						baseline_finish();
					}
					return;
				}
				currA = currA + 1;
				lastIsIncrease = false;
				if (currA > 8) {
					// Log.e(Contants.TAG, "currA = " + currA);
					// maybe this is workarround
					currA = 8;
					mWavelengthScanning.updateBaseline(currWl, currA, energy);
					// Log.d(Contants.TAG, "wl = " + currWl + ", a = " + currA
					// + ", energy = " + energy);
					// save baseline
					index = (int) currWl - 190;
					baseline[index] = currA;
					// Log.d(Contants.TAG, "save " + index + " = " + currA);
					if (currWl != startWl) {
						currWl = currWl - intervalWl;
						setWL(currWl);
						setA(currA);
						mCmdHandler
								.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
					} else {
						// Log.d(Contants.TAG, "wl = done2!!!!");
						baseline_finish();
					}
					// return;
				}
				setA(currA);
				mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
			}

			else {
				lastIsIncrease = false;
				mWavelengthScanning.updateBaseline(currWl, currA, energy);
				// Log.d(Contants.TAG, "wl = " + currWl + ", a = " + currA
				// + ", energy = " + energy);
				// save baseline
				index = (int) currWl - 190;
				baseline[index] = currA;
				// Log.d(Contants.TAG, "save " + index + " = " + currA);
				if (currWl != startWl) {
					currWl = currWl - intervalWl;
					setWL(currWl);
					setA(currA);
					mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
				} else {
					// Log.d(Contants.TAG, "wl = done2!!!!");
					baseline_finish();
				}
			}
		}
	}

	public void baseline_save() {
		OnlabApplication.getInstance().getSpUtil().setBaselineCreated();
		OnlabApplication.getInstance().getSpUtil().saveBaseline(baseline);
	}

	private void baseline_finish() {
		// OnlabApplication.getInstance().getSpUtil().setBaselineCreated();
		// OnlabApplication.getInstance().getSpUtil().saveBaseline(baseline);
		pause = false;
		mWavelengthScanning.baselineFinish();
	}

	public void prepareTest(float startWl, float endWl, float interval) {
		startTestWl = startWl;
		endTestWl = endWl;
		intervaTestlWl = interval;
		currTestWl = startTestWl;
		wsTestRunning = true;
	}

	public void stopWsTest() {
		wsTestRunning = false;
	}

	public void doTest(float wl, float abs, float trans, int energy) {
		int[] base = OnlabApplication.getInstance().getSpUtil().getBaseline();
		int a = base[(int) wl - 190];
		pause2 = true;
		currTestWl = wl;

		if (!wsTestRunning)
			return;

		if (wl < (startTestWl - intervaTestlWl)) {
			Log.d(Contants.TAG, "DONE!!");
			mWavelengthScanning.wsTestDone();
			pause2 = false;
			return;
		} else if (wl == endTestWl) {
			Log.d(Contants.TAG, "START!!");
			setWL(wl);
			setA(a);
			mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
			currTestWl = currTestWl - intervaTestlWl;

			return;
		}
		pause2 = true;
		// update ui
		mWavelengthScanning.updateChart((currTestWl + intervaTestlWl), abs,
				trans, energy, false);
		setWL(wl);
		setA(a);
		currTestWl = currTestWl - intervaTestlWl;
		mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
	}

	public void doRezero(float wl, float abs, float trans, int energy) {
		int[] base = OnlabApplication.getInstance().getSpUtil().getBaseline();
		int a = base[(int) wl - 190];
		isRezeroing = true;
		currTestWl = wl;

		if (!wsTestRunning)
			return;

		if (wl < (startTestWl - intervaTestlWl)) {
			Log.d(Contants.TAG, "REZERO DONE!!");
			isRezeroing = false;
			mWavelengthScanning.rezeroFinish();
			return;
		} else if (wl == endTestWl) {
			Log.d(Contants.TAG, "REZERO START!!");
			setWL(wl);
			setA(a);
			rezero();
			mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
			currTestWl = currTestWl - intervaTestlWl;
			return;
		}
		isRezeroing = true;
		// update ui
		mWavelengthScanning.updateChart((currTestWl + intervaTestlWl), abs,
				trans, energy, true);
		setWL(wl);
		setA(a);
		rezero();
		currTestWl = currTestWl - intervaTestlWl;
		mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);
	}

	public int getRealEnergy(float wl, int sa) throws InterruptedException {
		int energy = 0;
		pause = true;
		setWL(1000);
		setA(8);
		mCmdHandler.sendEmptyMessage(OnlabUVDevice.CMD_GET_ENERGY);

		return energy;
	}

	private void param_setting() {
		if (mPhotometryMeasurement.isAdded()) {
			mPhotometryMeasurement.setting();
		} else if (mQuantitativeAnalysis.isAdded()) {
			mQuantitativeAnalysis.setting();
		} else if (mWavelengthScanning.isAdded()) {
			mWavelengthScanning.setting();
		} else if (mTimeScanning.isAdded()) {
			mTimeScanning.setting();
		}
	}

	private void save() {
		if (mPhotometryMeasurement.isAdded()) {
			mPhotometryMeasurement.save();
		} else if (mQuantitativeAnalysis.isAdded()) {
			mQuantitativeAnalysis.save();
		} else if (mTimeScanning.isAdded()) {
			mTimeScanning.save();
		} else if (mWavelengthScanning.isAdded()) {
			mWavelengthScanning.save();
		}
	}

	public void open() {
		new AlertDialog.Builder(this)
				.setTitle(getString(R.string.history_dialog_title))
				.setItems(R.array.exp_name,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								// TODO Auto-generated method stub
								List<String> names;
								switch (which) {
								case 0:
									names = OnlabApplication.getInstance()
											.getPhotoMeasureDB().getTables();
									if (names.size() == 0) {
										mToast.toastShow(getString(R.string.record_is_null));
										return;
									}
									mHistoryExperimentDialog.setId(which);
									mHistoryExperimentDialog.setData(names);
									mHistoryExperimentDialog.show();
									break;
								case 1:
									names = OnlabApplication.getInstance()
											.getQuantitativeAnalusisDB()
											.getTables();
									if (names.size() == 0) {
										mToast.toastShow(getString(R.string.record_is_null));
										return;
									}
									mHistoryExperimentDialog.setId(which);
									mHistoryExperimentDialog.setData(names);
									mHistoryExperimentDialog.show();
									break;
								case 2:
									names = OnlabApplication.getInstance()
											.getWavelengthScanningDB()
											.getTables();
									if (names.size() == 0) {
										mToast.toastShow(getString(R.string.record_is_null));
										return;
									}
									mHistoryExperimentDialog.setId(which);
									mHistoryExperimentDialog.setData(names);
									mHistoryExperimentDialog.show();
									break;
								case 3:
									names = OnlabApplication.getInstance()
											.getTimeScanningDB().getTables();
									if (names.size() == 0) {
										mToast.toastShow(getString(R.string.record_is_null));
										return;
									}
									mHistoryExperimentDialog.setId(which);
									mHistoryExperimentDialog.setData(names);
									mHistoryExperimentDialog.show();
									break;

								default:
									break;
								}
							}
						}).show();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (v.getId() == R.id.mBTImageView) {
			if (!OnlabUVDevice.getInstance().isBleConnected()) {
				mBleSelectDialog.clear();
				mBleSelectDialog.show();
				OnlabUVDevice.getInstance().scanLeDevice(true);
			} else {
				// disconnectBle();
			}
			// if (!OnlabUVDevice.getInstance().isBleConnected()) {
			// OnlabUVDevice.getInstance().connect();
			// }
		} else if (v.getId() == R.id.dialog_wavelength_ok_button) {
			if (mWavelengthDialog.getWavelengthEditText().length() < 1) {
				mToast.toastShow(getString(R.string.input_correct_wavelength));
			} else {
				String wlString = mWavelengthDialog.getWavelengthEditText();
				float wl = Float.parseFloat(wlString);
				setWL(wl);
				// update ui
				// setWavelength(wl);
				dismissSetWavelengthDialog();
			}
		} else if (v.getId() == R.id.dialog_wavelength_cancel_button) {
			// mToast.toastShow("cancel");
			dismissSetWavelengthDialog();
		}
	}

	public void setMainButtonsEnable() {
		mMain.setButtonsEnable(true);
	}
}
